package com.hb.trade.server.project.proj.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.hb.core.pojo.parent.PageResult;
import com.hb.core.pojo.project.notice.entity.Notice;
import com.hb.core.pojo.project.proj.dto.InquiryProjectThanDTO;
import com.hb.core.pojo.project.proj.entity.AbstractProject;
import com.hb.core.pojo.project.proj.entity.QueryProject;
import com.hb.core.pojo.project.proj.enums.BidWayEnum;
import com.hb.core.pojo.project.section.dto.BidSectionDTO;
import com.hb.core.pojo.project.section.entity.BidSection;
import com.hb.trade.server.project.notice.service.NoticeService;
import com.hb.trade.server.project.proj.manager.AbstractProjectManager;
import com.hb.trade.server.project.proj.service.ProjectService;
import com.hb.trade.server.project.section.service.raw.BidSectionService;
import com.hb.trade.server.project.util.DataDockConfig;
import io.swagger.annotations.Api;
import org.fzzn.core.model.enums.MsgEnum;
import org.fzzn.core.model.msg.Message;
import org.fzzn.core.util.Enums;
import org.fzzn.core.util.MsgUtil;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * 项目信息表 前端控制器
 *
 * @author zhaojk
 * @since 2021-08-30
 */
@Api(tags = "项目信息")
@RestController
public class ProjectController {

    protected final ProjectService projectService;
    protected final BidSectionService bidSectionService;
    protected final NoticeService noticeService;

    public ProjectController(ProjectService projectService,
                             BidSectionService bidSectionService, NoticeService noticeService) {
        this.projectService = projectService;
        this.bidSectionService = bidSectionService;
        this.noticeService = noticeService;
    }

    @PostMapping("/project/projects")
    public Message<PageResult<AbstractProject>> projects(@RequestBody QueryProject project) {
        // 项目类型, 该字段必填
        Integer bidWay = project.getBidWay();
        IPage<AbstractProject> projects;
        if (bidWay == null) {
            projects = projectService.pageProjects(project);
        } else {
            BidWayEnum bidWayEnum = Enums.of(BidWayEnum.class, bidWay);
            if (bidWayEnum == null) {
                return MsgUtil.fail("未知的项目类型, bidWay: [" + bidWay + "]");
            }
            projects = projectService.pageProjects(project, bidWayEnum);
        }
        PageResult<AbstractProject> tPageResult = PageResult.get(projects);
        return MsgUtil.success(tPageResult);
    }

    /**
     * 该接口的参数类型参照 fzzn.trade.entity.project.dto 包下的结构进行传值
     *
     * @param projectJSON
     * @return
     * @see InquiryProjectThanDTO
     */
    @PostMapping("/project/newProject")
    public Message<Boolean> newProject(@RequestBody JSONObject projectJSON) {
        String valid = AbstractProjectManager.valid(projectJSON);
        if (StrUtil.isNotEmpty(valid)) {
            return MsgUtil.fail(valid);
        }
        JSONArray sectionJSONArray = projectJSON.getJSONArray("sections");
        if (CollUtil.isEmpty(sectionJSONArray)) {
            return MsgUtil.fail("至少填写一个标段信息");
        }
        Integer bidWay = projectJSON.getInt("bidWay");
        BidWayEnum bidWayEnum = Enums.of(BidWayEnum.class, bidWay);
        //项目编号
        String tenderProjectCode = projectJSON.get("tender_project_code", String.class);
        if (StrUtil.isEmpty(tenderProjectCode) && StrUtil.length(DataDockConfig.projectCodeSuffix) != 2) {
            return MsgUtil.fail("项目编号后缀必须设置为两位,请联系平台管理员修改");
        }
        boolean result = projectService.insertProjectWithoutAudit(projectJSON, bidWayEnum);
        return MsgUtil.msg(result);
    }

    /**
     * 查询项目详情
     *
     * @param project
     * @return
     */
    @PostMapping("/project/detail")
    public Message<AbstractProject> projectDetail(@RequestBody AbstractProject project) {
        // 查询项目详情, 方法返回的是项目的实际类型, 即子类, 可以根据bidWay强转
        AbstractProject rawProject = projectService.getByPrimaryKey(project.getId());
        // 查询标段
        if (Boolean.TRUE.equals(project.getWithSections())) {
            // 查询标段信息
            List<BidSectionDTO> sectionDtos = bidSectionService.findByProjectId(rawProject.getId());
            rawProject.setSections(sectionDtos);
        }
        return MsgUtil.msg(rawProject);
    }

    /**
     *
     * @Description: 根据标段id查询项目的详情
     * @Author: zhongdl
     * @Date:2022/2/25 10:44
     * @param sectionId: 标段id
     * @return: {@link Message< AbstractProject> }
     **/
    @PostMapping("/project/detailBySectionId")
    public Message<AbstractProject> projectDetail(@RequestBody Long sectionId) {
        BidSection bidSection = bidSectionService.getById(sectionId);
        // 查询项目详情, 方法返回的是项目的实际类型, 即子类, 可以根据bidWay强转
        AbstractProject rawProject = projectService.getByPrimaryKey(bidSection.getProjectId());
        return MsgUtil.success(rawProject);
    }

    /**
     * 该接口的参数类型参照 fzzn.trade.entity.project.dto 包下的结构进行传值
     *
     * @param projectJSON
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @PostMapping("/project/update")
    public Message<Boolean> updateNewProject(@RequestBody JSONObject projectJSON) {
        Long projectId = projectJSON.getLong("id");
        AbstractProject project = projectService.getById(projectId);

        BeanUtil.copyProperties(projectJSON, project);
        boolean update = projectService.updateProjectById(project);

        // 保存标段
        JSONArray sectionJSONArray = projectJSON.getJSONArray("sections");
        List<BidSectionDTO> sections = sectionJSONArray.toList(BidSectionDTO.class);
        boolean result = bidSectionService.saveSections(projectId, null, sections);
        /* 因为这里项目是更新的工作流添加的项目信息, 所以这里添加标段信息单独拿出来, 不建议放在 updateProjectById 方法中操作 */
        return MsgUtil.msg(update);
    }

    /**
     *
     * @Description: 查询未推送过的项目列表
     * @Author: zhongdl
     * @Date:2022/2/17 15:35
     * @param projectJSON:
     * @return: {@link Message< List<  AbstractProject >> }
     **/
    @PostMapping("/project/listProjectAllFieldsDTO")
    Message<List<AbstractProject>> listProjectAllFieldsDTO(@RequestBody JSONObject projectJSON) {
        List<AbstractProject> listProjectAllFieldsDTO = projectService.listProjectAllFieldsDTO();
        if (CollUtil.isEmpty(listProjectAllFieldsDTO)) {
            return MsgUtil.success(listProjectAllFieldsDTO);
        }
        for (AbstractProject abstractProject : listProjectAllFieldsDTO) {
            List<BidSectionDTO> sectionDtos = bidSectionService.findByProjectId(abstractProject.getId());
            abstractProject.setSections(sectionDtos);
        }
        return MsgUtil.success(listProjectAllFieldsDTO);
    }

    /**
     * @Description: 项目列表伪删除
     *
     * @author yuezheng
     * @param abstractProject
     * @return org.fzzn.core.model.msg.Message
     * @date 2022/6/30 16:46
     */
    @PostMapping("/project/deleteProjectById")
    Message deleteProjectById(@RequestBody AbstractProject abstractProject) {
        if (abstractProject == null || abstractProject.getId() == null) {
            return MsgUtil.fail(MsgEnum.INCORRECT_PARAM.msg());
        }
        List<Notice> noticeList = noticeService.findNoticeByProjectId(abstractProject.getId());
        if (CollUtil.isNotEmpty(noticeList)) {
            return MsgUtil.fail("禁止删除:该项目已存在公告");
        }
        Boolean delete = this.projectService.deleteProjectById(abstractProject.getId());
        return delete ? MsgUtil.success() : MsgUtil.fail(MsgEnum.FAILURE.msg());
    }
}
